package com.heyqing.topic.IsBalanced_0110;

import java.util.Objects;

/**
 * ClassName:IsBalanced
 * Package:com.heyqing.topic.IsBalanced_0110
 * Description:
 *
 * @Date:2024/9/14
 * @Author:Heyqing
 */
public class IsBalanced {
    private boolean flag = false;
    private boolean res = true;

    private int depth = 0;

    public boolean isBalanced(TreeNode root) {
        if (Objects.isNull(root)) return true;
        achieveFunc(root.left, root.right);
        return res;
    }

    private void achieveFunc(TreeNode left, TreeNode right) {
        if (Objects.isNull(left) || Objects.isNull(right)){
            if (Objects.isNull(left) && Objects.isNull(right)){
                return;
            }
            if (Objects.isNull(left) && Objects.nonNull(right)){
                if (Objects.nonNull(right.left) || Objects.nonNull(right.right)){
                    flag = true;
                    res = false;
                    return;
                }else {
                    return;
                }
            }else {
                if (Objects.nonNull(left.left) || Objects.nonNull(left.right)){
                    flag = true;
                    res = false;
                    return;
                }else {
                    return;
                }
            }
        }
        if (flag) return;
        getMaxDepth(left, 0);
        int leftMaxDepth = depth;
        depth = 0;
        getMaxDepth(right, 0);
        int rightMaxDepth = depth;
        depth = 0;
        if (Math.abs(leftMaxDepth - rightMaxDepth) > 1) {
            flag = true;
            res = false;
            return;
        }
        achieveFunc(left.left, left.right);
        achieveFunc(right.left, right.right);
    }

    private void getMaxDepth(TreeNode root, int currentDepth) {
        if (Objects.isNull(root)) {
            return;
        }
        currentDepth++;
        if (Objects.isNull(root.left) && Objects.isNull(root.right)) {
            depth = Math.max(currentDepth, depth);
        }
        getMaxDepth(root.left, currentDepth);
        getMaxDepth(root.right, currentDepth);
        return;
    }

}
